"""
    CrunchyRoll;xbmc
    Copyright (C) 2012 - 2014 Matthew Beacher
    This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
import sys
import datetime
import urllib
import xbmc
import xbmcgui
import xbmcplugin
import crunchy_scraper
import re
import time
import xbmcaddon
__settings__ = xbmcaddon.Addon(id='plugin.video.crunchyroll-old')
__language__ = __settings__.getLocalizedString
from crunchy_video import CrunchyPlayback

class updateArgs:

	def __init__(self, *args, **kwargs):
		for key, value in kwargs.iteritems():
			if value == 'None':
				kwargs[key] = None
			else:
				kwargs[key] = urllib.unquote_plus(kwargs[key])
		self.__dict__.update(kwargs)

class UI:
	
	def __init__(self):
		self.main = Main(checkMode = False)
		xbmcplugin.setContent(int(sys.argv[1]), 'movies')

	def Language(self):
                self.Language = xbmc.Language(os.getcwd())
	
	def endofdirectory(self, sortMethod = 'none'):
		# set sortmethod to something xbmc can use
		if sortMethod == 'title':
			sortMethod = xbmcplugin.SORT_METHOD_LABEL
		elif sortMethod == 'none':
			sortMethod = xbmcplugin.SORT_METHOD_NONE
		elif sortMethod == 'date':
			sortMethod = xbmcplugin.SORT_METHOD_DATE
		#Sort methods are required in library mode.
		xbmcplugin.addSortMethod(int(sys.argv[1]), sortMethod)
		#let xbmc know the script is done adding items to the list.
		dontAddToHierarchy = False
		xbmcplugin.endOfDirectory(handle = int(sys.argv[1]), updateListing = dontAddToHierarchy)
			
	def addItem(self, info, isFolder=True, total_items = 0):
		#Defaults in dict. Use 'None' instead of None so it is compatible for quote_plus in parseArgs
		info.setdefault('url','None')
		info.setdefault('Thumb','None')
		info.setdefault('id','None')
		info.setdefault('page_url','None')
		info.setdefault('Icon','None')
		info.setdefault('resolutions','10')
		info.setdefault('plot','No description available.')
		print info
		#create params for xbmcplugin module
		u = sys.argv[0]+\
			'?url='+urllib.quote_plus(info['url'])+\
			'&mode='+urllib.quote_plus(info['mode'])+\
			'&name='+urllib.quote_plus(info['Title'])+\
			'&id='+urllib.quote_plus(info['id'])+\
			'&resolutions='+urllib.quote_plus(info['resolutions'])+\
			'&page_url='+urllib.quote_plus(info['page_url'])+\
			'&icon='+urllib.quote_plus(info['Thumb'])+\
			'&plot='+urllib.quote_plus(info['plot'])
		#create list item
		li=xbmcgui.ListItem(label = info['Title'], iconImage = info['Icon'], thumbnailImage = info['Thumb'])
		li.setInfo( type="Video", infoLabels={ "Title":info['Title'], "Plot":info['plot']})
		#for videos, replace context menu with queue and add to favorites
		if not isFolder:
			li.setProperty("IsPlayable", "true")#let xbmc know this can be played, unlike a folder.
			#add context menu items to non-folder items.
			contextmenu = [('Queue Video', 'Action(Queue)')]
		#for folders, completely remove contextmenu, as it is totally useless.
		else:
			li.addContextMenuItems([], replaceItems=True)
		#add item to list
		ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=u, listitem=li, isFolder=isFolder, totalItems=total_items)

	def showCategories(self):
                local_string = xbmcaddon.Addon(id='plugin.video.crunchyroll-old').getLocalizedString
                Anime = local_string(50000).encode("utf8")
                Drama = local_string(50004).encode("utf8")
                Queue = local_string(50005).encode("utf8")
                Pop = local_string(50009).encode("utf8")
                self.addItem({'Title':Queue, 'mode':'queue'})
		self.addItem({'Title':Anime, 'mode':'anime'})
		self.addItem({'Title':Drama, 'mode':'drama'})
		self.addItem({'Title':Pop, 'mode':'pop'})
		self.endofdirectory()
		
	def showAnime(self):
                local_string = xbmcaddon.Addon(id='plugin.video.crunchyroll-old').getLocalizedString
                All_Anime = local_string(50001).encode("utf8")
                Recently_Added = local_string(50002).encode("utf8")
                Simulcasts = local_string(50006).encode("utf8")
                Most_Popular = local_string(50003).encode("utf8")
                Browse_by_Genre = local_string(50007).encode("utf8")
                seasons = local_string(50010).encode("utf8")
		self.addItem({'Title':All_Anime, 'mode':'anime_all'})
		self.addItem({'Title':Recently_Added, 'mode':'EpBox_scraper', 'id':'anime_updated'})
		self.addItem({'Title':Simulcasts, 'mode':'SpBox_scraper', 'id':'anime_simulcasts'})
		self.addItem({'Title':Most_Popular, 'mode':'SpBox_scraper', 'id':'anime_popular'})
                self.addItem({'Title':Browse_by_Genre, 'mode':'anime_genre'})
                #self.addItem({'Title':seasons, 'mode':'anime_seasons'})
		self.endofdirectory()
		
	def animeGenre(self):
                local_string = xbmcaddon.Addon(id='plugin.video.crunchyroll-old').getLocalizedString
                Action = local_string(60001).encode("utf8")
                Adventure = local_string(60002).encode("utf8")
                Comedy = local_string(60003).encode("utf8")
                Drama = local_string(60004).encode("utf8")
                Ecchi = local_string(60005).encode("utf8")
                Fantasy = local_string(60006).encode("utf8")
                historical = local_string(60007).encode("utf8")
                Mecha = local_string(60008).encode("utf8")
                Romance = local_string(60009).encode("utf8")
                Science_Fiction = local_string(60010).encode("utf8")
                seinen = local_string(60011).encode("utf8")
                Shoujo = local_string(60012).encode("utf8")
                shounen = local_string(60013).encode("utf8")
                Slice_of_Life = local_string(60014).encode("utf8")
                Sports = local_string(60015).encode("utf8")
		self.addItem({'Title':Action, 'mode':'anime_withtag','id':'action'})
		self.addItem({'Title':Adventure, 'mode':'anime_withtag','id':'adventure'})
		self.addItem({'Title':Comedy, 'mode':'anime_withtag','id':'comedy'})
		self.addItem({'Title':Drama, 'mode':'anime_withtag','id':'drama'})
		self.addItem({'Title':Ecchi, 'mode':'anime_withtag','id':'ecchi'})
		self.addItem({'Title':Fantasy, 'mode':'anime_withtag','id':'fantasy'})
		self.addItem({'Title':historical, 'mode':'anime_withtag','id':'historical'})
		self.addItem({'Title':Mecha, 'mode':'anime_withtag','id':'mecha'})
		self.addItem({'Title':Romance, 'mode':'anime_withtag','id':'romance'})
		self.addItem({'Title':Science_Fiction, 'mode':'anime_withtag','id':'science_fiction'})
		self.addItem({'Title':seinen, 'mode':'anime_withtag','id':'seinen'})
		self.addItem({'Title':Shoujo, 'mode':'anime_withtag','id':'shoujo'})
		self.addItem({'Title':shounen, 'mode':'anime_withtag','id':'shounen'})
		self.addItem({'Title':Slice_of_Life, 'mode':'anime_withtag','id':'slice_of_life'})
		self.addItem({'Title':Sports, 'mode':'anime_withtag','id':'sports'})
		self.endofdirectory()

        def showDrama(self):                
                local_string = xbmcaddon.Addon(id='plugin.video.crunchyroll-old').getLocalizedString
                All_Drama = local_string(50008).encode("utf8")
                Recently_Added = local_string(50002).encode("utf8")
                Simulcasts = local_string(50006).encode("utf8")
                Most_Popular = local_string(50003).encode("utf8")
                Browse_by_Genre = local_string(50007).encode("utf8")
                seasons = local_string(50010).encode("utf8")
		self.addItem({'Title':All_Drama, 'mode':'drama_all'})
		self.addItem({'Title':Recently_Added, 'mode':'EpBox_scraper', 'id':'drama_updated'})
		self.addItem({'Title':Most_Popular, 'mode':'SpBox_scraper', 'id':'drama_popular'})
		self.addItem({'Title':Simulcasts, 'mode':'SpBox_scraper', 'id':'drama_simulcasts'})
                self.addItem({'Title':Browse_by_Genre, 'mode':'drama_genre'})
                #self.addItem({'Title':seasons, 'mode':'drama_seasons'})
		self.endofdirectory()

	def dramaGenre(self):
                local_string = xbmcaddon.Addon(id='plugin.video.crunchyroll-old').getLocalizedString
                Chinese = local_string(60050).encode("utf8")
                Japanese = local_string(60051).encode("utf8")
                Korean = local_string(60052).encode("utf8")
                Singaporean = local_string(60053).encode("utf8")
                Action = local_string(60001).encode("utf8")
                Comedy = local_string(60003).encode("utf8")
                Crime = local_string(60054).encode("utf8")
                Family = local_string(60055).encode("utf8")
                Food = local_string(60056).encode("utf8")
                Historical = local_string(60007).encode("utf8")
                Horror = local_string(60057).encode("utf8")
                Martial_Arts = local_string(60058).encode("utf8")
                Romance = local_string(60009).encode("utf8")
                Thriller = local_string(60059).encode("utf8")
		self.addItem({'Title':Chinese, 'mode':'drama_withtag','id':'cdrama'})
		self.addItem({'Title':Japanese, 'mode':'drama_withtag','id':'jdrama'})
		self.addItem({'Title':Korean, 'mode':'drama_withtag','id':'kdrama'})
		self.addItem({'Title':Singaporean, 'mode':'drama_withtag','id':'sgdrama'})
		self.addItem({'Title':Action, 'mode':'drama_withtag','id':'action'})
		self.addItem({'Title':Comedy, 'mode':'drama_withtag','id':'comedy'})
		self.addItem({'Title':Crime, 'mode':'drama_withtag','id':'crime'})
		self.addItem({'Title':Family, 'mode':'drama_withtag','id':'family'})
		self.addItem({'Title':Food, 'mode':'drama_withtag','id':'food'})
		self.addItem({'Title':Historical, 'mode':'drama_withtag','id':'historical'})
		self.addItem({'Title':Horror, 'mode':'drama_withtag','id':'horror'})
		self.addItem({'Title':Martial_Arts, 'mode':'drama_withtag','id':'martial_arts'})
		self.addItem({'Title':Romance, 'mode':'drama_withtag','id':'romance'})
		self.addItem({'Title':Thriller, 'mode':'drama_withtag','id':'thriller'})
		self.endofdirectory()

	def pop_genre(self):                
                local_string = xbmcaddon.Addon(id='plugin.video.crunchyroll-old').getLocalizedString
                Popular = local_string(50003).encode("utf8")
                Recently_Added = local_string(50002).encode("utf8")
                JMusic = local_string(60075).encode("utf8")
                KPop = local_string(60076).encode("utf8")
                Culture = local_string(60077).encode("utf8")
                Reviews = local_string(60078).encode("utf8")
                Fashion = local_string(60079).encode("utf8")
                Cosplay = local_string(60080).encode("utf8")
                Food = local_string(60081).encode("utf8")
                Gaming = local_string(60082).encode("utf8")
		self.addItem({'Title':Popular, 'mode':'EpBox_scraper','id':'pop_popular'})
		self.addItem({'Title':Recently_Added, 'mode':'EpBox_scraper','id':'pop_updated'})
		self.addItem({'Title':JMusic, 'mode':'pop_withtag', 'id':'jmusic'})
		self.addItem({'Title':KPop, 'mode':'pop_withtag', 'id':'kpop'})
                self.addItem({'Title':Culture, 'mode':'pop_withtag', 'id':'culture'})
                self.addItem({'Title':Reviews, 'mode':'pop_withtag', 'id':'reviews'})
		self.addItem({'Title':Fashion, 'mode':'pop_withtag', 'id':'fashion'})
		self.addItem({'Title':Cosplay, 'mode':'pop_withtag', 'id':'cosplay'})
		self.addItem({'Title':Food, 'mode':'pop_withtag', 'id':'food'})
		self.addItem({'Title':Gaming, 'mode':'pop_withtag', 'id':'gaming'})
		self.endofdirectory()

	def Seasons(self):      
                mode = self.main.args.mode
                local_string = xbmcaddon.Addon(id='plugin.video.crunchyroll-old').getLocalizedString
                Winter = local_string(60101).encode("utf8")
                Spring = local_string(60102).encode("utf8")
                Summer = local_string(60103).encode("utf8")
                Fall = local_string(60104).encode("utf8")
                d = datetime.datetime.now()
                d_year = d.strftime("%Y")
                d_month = d.strftime("%m")
                if mode is 'anime_seasons':
                        count = 2009
                        sendmode = "aseason"
                else:
                        count = 2012
                        sendmode = "dseason"
                endcound = int(d_year)
                notDone = True
                if int(d_month) >= 10:
                        self.addItem({'Title':Fall+' '+str(endcound), 'mode':sendmode, 'id':"Fall-"+str(endcound)})
                if int(d_month) >= 7:
                        self.addItem({'Title':Summer+' '+str(endcound), 'mode':sendmode, 'id':"Summer-"+str(endcound)})
                if int(d_month) >= 4:
                        self.addItem({'Title':Spring+' '+str(endcound), 'mode':sendmode, 'id':"Spring-"+str(endcound)})
                        self.addItem({'Title':Winter+' '+str(endcound), 'mode':sendmode, 'id':"Winter-"+str(endcound)})
                while notDone:
                        endcound = endcound - 1
                        self.addItem({'Title':Fall+' '+str(endcound), 'mode':sendmode, 'id':"Fall-"+str(endcound)})
                        self.addItem({'Title':Summer+' '+str(endcound), 'mode':sendmode, 'id':"Summer-"+str(endcound)})
                        self.addItem({'Title':Spring+' '+str(endcound), 'mode':sendmode, 'id':"Spring-"+str(endcound)})
                        self.addItem({'Title':Winter+' '+str(endcound), 'mode':sendmode, 'id':"Winter-"+str(endcound)})
                        if endcound == count:
                                notDone = False                                
		self.endofdirectory()

	
	def episodes(self):
		crunchy_scraper.CrunchyScraper().getEpisodeListing(self.main.args.page_url)

	def queue(self):
                crunchy_scraper.CrunchyScraper().getQueue()

        def series_alpha(self):
                crunchy_scraper.CrunchyScraper().getTitleOnlyScrappedSeries(self.main.args.mode)

        def EpBox_Scraper(self):
                crunchy_scraper.CrunchyScraper().getEpBoxScrappedSeries(self.main.args.id)

        def SpBox_scraper(self):
                crunchy_scraper.CrunchyScraper().getSpBoxScrappedSeries(self.main.args.mode, self.main.args.id)
		
	def startVideo(self):
		CrunchyPlayback().startPlayback(self.main.args.id, self.main.args.page_url, self.main.args.resolutions)

	def Fail(self):
                local_string = xbmcaddon.Addon(id='plugin.video.crunchyroll-old').getLocalizedString
                badstuff = local_string(70007).encode("utf8")
		self.addItem({'Title':badstuff,'mode':'none'})
		print "Crunchyroll takeout --> crunchy_main.py checkMode fall through"
		self.endofdirectory()

class Main:

	def __init__(self, checkMode = True):
		#self.user = None
		self.parseArgs()
		if checkMode:
			self.checkMode()

	def parseArgs(self):
		# call updateArgs() with our formatted argv to create the self.args object
		if (sys.argv[2]):
			exec "self.args = updateArgs(%s')" % (sys.argv[2][1:].replace('&', "',").replace('=', "='"))
		else:
			# updateArgs will turn the 'None' into None.
			# Don't simply define it as None because unquote_plus in updateArgs will throw an exception.
			# This is a pretty ugly solution
			self.args = updateArgs(mode = 'None', url = 'None', name = 'None')

	def checkMode(self):
		mode = self.args.mode
		if mode is None:
			UI().showCategories()
		elif mode == 'series':
			UI().episodes()
		elif mode == 'episode':
			UI().startVideo()
		elif mode == 'queue':
			UI().queue()
		elif mode == 'anime':
			UI().showAnime()
		elif mode == 'drama':
			UI().showDrama()
		elif mode == 'anime_genre':
			UI().animeGenre()
		elif mode == 'drama_genre':
			UI().dramaGenre()
		elif mode == 'pop':
			UI().pop_genre()
		elif mode == 'anime_seasons' or mode == 'drama_seasons':
			UI().Seasons()
		elif mode == 'anime_all' or mode == 'drama_all':
			UI().series_alpha()
		elif mode == 'EpBox_scraper':
			UI().EpBox_Scraper()
		elif mode == 'SpBox_scraper' or mode == 'anime_withtag' or mode == 'drama_withtag' or mode == 'pop_withtag' or mode == 'dseason' or mode == 'aseason':
			UI().SpBox_scraper()
		else:
                        UI().Fail()


